import React, { useEffect, useRef } from 'react';

const Front: React.FC = () => {
  const cv: any = useRef(HTMLDivElement);
  const drawFlow = () => {
    let canvas: HTMLCanvasElement = document.querySelector('canvas') as HTMLCanvasElement;
    canvas.width = cv.current.offsetWidth;
    canvas.height = cv.current.offsetHeight;
    let ut: WebGLUniformLocation,
      gl: WebGLRenderingContext,
      st = Date.now();

    function initShaders(gl: WebGLRenderingContext) {
      let vertexShader: WebGLShader = gl.createShader(gl.VERTEX_SHADER) as WebGLShader;
      gl.shaderSource(
        vertexShader,
        `
      attribute vec4 vPosition;
      void main (void) {
          gl_Position = vPosition;
      }
      `,
      );
      gl.compileShader(vertexShader);

      if (!gl.getShaderParameter(vertexShader, gl.COMPILE_STATUS)) {
      }
      let fragmentShader: WebGLShader = gl.createShader(gl.FRAGMENT_SHADER) as WebGLShader;
      gl.shaderSource(
        fragmentShader,
        `
      precision mediump float;

      uniform float time;
      uniform vec2 resolution;

      void main(void) {
          vec2 q = gl_FragCoord.xy / resolution.xy;
          vec2 p = -1.0 + 2.0 * q;
          p.x *= resolution.x / resolution.y;

          float v = p.x + cos(time + p.y);
          vec3 col = vec3(0.1 * max(0.0, p.y), 0.1 * max(0.1, p.x), 0.2 * max(0.1, p.x)) / abs(v * 2.0);
          gl_FragColor = vec4(col, 1.0);
      }
      `,
      );
      gl.compileShader(fragmentShader);

      if (!gl.getShaderParameter(fragmentShader, gl.COMPILE_STATUS)) {
      }

      let program: WebGLProgram = gl.createProgram() as WebGLProgram;
      gl.attachShader(program, vertexShader);
      gl.attachShader(program, fragmentShader);
      gl.linkProgram(program);
      gl.useProgram(program);

      return program;
    }

    function initGraphics() {
      gl = canvas.getContext('webgl') as WebGLRenderingContext;
      let width = canvas.width;
      let height = canvas.height;
      gl.viewport(0, 0, width, height);

      let program = initShaders(gl);
      let buffer = gl.createBuffer();
      gl.bindBuffer(gl.ARRAY_BUFFER, buffer);

      gl.bufferData(
        gl.ARRAY_BUFFER,
        new Float32Array([-1, 1, -1, -1, 1, -1, 1, 1]),
        gl.STATIC_DRAW,
      );

      let vPosition = gl.getAttribLocation(program, 'vPosition');
      gl.vertexAttribPointer(vPosition, 2, gl.FLOAT, false, 0, 0);
      gl.enableVertexAttribArray(vPosition);

      ut = gl.getUniformLocation(program, 'time') as WebGLUniformLocation;
      let resolution = new Float32Array([canvas.width, canvas.height]);
      gl.uniform2fv(gl.getUniformLocation(program, 'resolution'), resolution);
    }

    function render() {
      gl.uniform1f(ut, (Date.now() - st) / 1000);
      gl.drawArrays(gl.TRIANGLE_FAN, 0, 4);
      requestAnimationFrame(render);
    }

    initGraphics();
    render();
  };
  window.addEventListener('resize', drawFlow);
  useEffect(() => {
    drawFlow();
    return () => {
      window.removeEventListener('resize', drawFlow);
    };
  }, []);
  return (
    <div style={{ height: '100%', position: 'relative' }} ref={cv}>
      <canvas style={{ height: '100%', width: '100%', position: 'absolute' }}></canvas>
    </div>
  );
};

export default Front;
